package com.kusiri.kframework.salesforce.ui
{
	import com.kusiri.kframework.salesforce.action.OpenSObjectViewAction;
	import com.kusiri.kframework.salesforce.model.IKfSalesforceModel;
	import com.kusiri.kframework.salesforce.model.ISObject;
	import com.kusiri.kframework.salesforce.model.SObject;
	import com.kusiri.kframework.salesforce.util.SfUtil;
	import com.salesforce.results.Field;
	import com.salesforce.results.PickListEntry;
	import com.salesforce.results.PicklistForRecordType;
	import com.salesforce.results.RecordTypeMapping;
	
	import flash.events.MouseEvent;
	
	import mx.collections.ArrayCollection;
	import mx.containers.Form;
	import mx.containers.FormItem;
	import mx.controls.Button;
	import mx.controls.ComboBox;
	import mx.controls.DateField;
	import mx.controls.Text;
	import mx.controls.TextArea;
	import mx.controls.TextInput;
	import mx.core.UIComponent;
	import mx.formatters.DateFormatter;
	
	public class SObjectFormUtil
	{
		
		/**
		 * Data for picklists etc.
		 */
		private var dataProviders:Object = new Object();
		
		private var dateFormatter:DateFormatter = new DateFormatter();
		
		public function SObjectFormUtil()
		{

		}

		public function getSfValueFromFormControl(formControl:Object) : String
		{
			if (formControl is DateField)
			{
				return SfUtil.dateToDateString(formControl.selectedDate);
			}
			if (formControl is ReferenceInput)
			{
				return ReferenceInput(formControl).sobject ? ReferenceInput(formControl).sobject.Id : null;
			}
			return formControl.text;
		}

		public function setFormFieldsFromSObject(form:Form, sobject:SObject) : void
		{
		    // get form items
		    var formItems:Object = form.getChildren();
		
		    // loop items and add values
		    for (var i:int = 0; i < formItems.length; i++)
		    {
		    	if (formItems[i] is FormItem)
		    	{
		        	setFormValueFromSObject(formItems[i].getChildAt(0), sobject);
		     	}
		    }
		    				
		}

		public function setFormValueFromSObject(formControl:Object, sobject:ISObject) : void
		{
			
			
			var fieldName:String = formControl.name;
			
			var value:* = sobject[fieldName];
			
			var field:Field = sobject.__sfDescription.fields[fieldName];

			if (formControl is DateField)
			{
				formControl.selectedDate = value;
				return;
			}
			if (formControl is ComboBox)
			{
				var ac:ArrayCollection = formControl.dataProvider;
				for(var i:int=0, j:int=ac.length; i<j; i++)
				{
					if (ac[i].data == value)
					{
						formControl.selectedItem = ac[i];
						break;
					}
				}
				return;
			}
			if (formControl is ReferenceInput)
			{
				formControl.sobject = sobject[field.relationshipName] as SObject;
				return;
			}
		
			// default
			formControl.text = value;
		
			
		}
		
		/**
		 * returns object with properties dataProvider and defaultIndex
		 */
		public function getDataProviderFor(sobjectType:String, fieldName:String, usedMapping:RecordTypeMapping) : Object
		{
			var key:String = sobjectType+'.'+fieldName+'.'+usedMapping.layoutId;
			
			if (dataProviders.hasOwnProperty(key))
			{
				return dataProviders[key];
			}
			
			/*
			
			Using the layouts now
			
			var field:Field = Field(sfApi.descriptions[sobjectType].fields[fieldName]);
			var dataProvider:ArrayCollection = new ArrayCollection();
			
			for(var i:int=0,j:int=field.picklistValues.length;i<j; i++)
			{
				var entry:PickListEntry = PickListEntry(field.picklistValues.getItemAt(i));
				dataProvider.addItem({data:entry.value, label:entry.label});
			}
			*/
			
			var dataProvider:ArrayCollection = new ArrayCollection();
			var defaultIndex:int = 0; 
			var picklist:PicklistForRecordType;
			for(var i:int=0,j:int=usedMapping.picklistsForRecordType.length;i<j; i++)
			{
				picklist = usedMapping.picklistsForRecordType[i];
				if (picklist.picklistName == fieldName) break;
			}
			
			for (i=0, j=picklist.picklistValues.length; i<j; i++)
			{
				var entry:PickListEntry = PickListEntry(picklist.picklistValues[i]);
				if (entry.active) dataProvider.addItem({data:entry.value, label:entry.label});
				if (entry.defaultValue) defaultIndex = i;
			}
			
			dataProviders[key] = {dataProvider:dataProvider, defaultIndex:defaultIndex};
			
			return dataProviders[key];
		}
		
		
		public function getFormField(sobject:ISObject, fieldName:String, field:Field, usedMapping:RecordTypeMapping) : UIComponent
		{
			var control:UIComponent = _getControl(sobject, field, usedMapping);
			
			control.name = fieldName;
			if (sobject.Id != null) setFormValueFromSObject(control, sobject);
			return control;
		}
		
		private function _getControl(sobject:ISObject, field:Field, usedMapping:RecordTypeMapping) : UIComponent
		{
			//if (field.type == 'boolean') return getTextInput(field);
			if (field.type == 'reference') return getReferenceInput(field, sobject.__model);
			//if (field.type == 'datetime') return getTextInput(field);
			//if (field.type == 'int') return getTextInput(field);
			if (field.type == 'string') return getTextInput(field);
			if (field.type == 'textarea') return getTextArea(field);
			if (field.type == 'date') return getDateInput(field);
			if (field.type == 'picklist') return getPicklist(sobject, field, usedMapping);
			if (field.type == 'combobox') return getTextInput(field);
			
			return new TextInput();
		}
		
		private function getTextArea(field:Field) : UIComponent
		{
			var control:TextArea = new TextArea();
			control.maxChars = field.length
			return control;
		}

		private function getReferenceInput(field:Field, model:IKfSalesforceModel) : ReferenceInput
		{
			var control:ReferenceInput = new ReferenceInput();
			control.field = field;
			control.model = model;
			return control;
		}
		
		private function getTextInput(field:Field) : UIComponent
		{
			var control:TextInput = new TextInput();
			if (field.length) control.maxChars = field.length
			control.text = SfUtil.processSfFormula(field.defaultValueFormula);
			return control;
		}
    		
		private function getDateInput(field:Field) : UIComponent
		{
			var control:DateField = new DateField();
			return control;
		}
		
		private function getPicklist(sobject:ISObject, field:Field, usedMapping:RecordTypeMapping) : UIComponent
		{
			var control:ComboBox = new ComboBox();			
			var o:Object = getDataProviderFor(sobject.__type, field.name, usedMapping);
			control.dataProvider = o.dataProvider;
			control.selectedIndex = o.defaultIndex;
			return control;
		}

		public function getReadOnlyFormField(sobject:ISObject, fieldName:String, field:Field) : UIComponent
		{

			
			if (field.type == 'reference' && sobject[fieldName]) 
			{
				var referencedSObject : SObject = sobject[field.relationshipName];
				
				if (referencedSObject && referencedSObject.__type != 'User') 
				{
					var b:Button = new Button();
					b.label =  referencedSObject.__displayName;			
					b.addEventListener(MouseEvent.CLICK, 
						function(e:*) : void 
						{
							var action : OpenSObjectViewAction = new OpenSObjectViewAction();
							action.valueObject = referencedSObject;
							action.execute();
						}, false, 0, true
					);
					b.name = fieldName;
					return b;
				}
			}

			var t:Text =  new Text();
			t.text = sobject.__getPropertyAsText(fieldName);
			t.name = fieldName;
			
			//TODO: remove this
			t.setStyle('color', '#000000');
			t.setStyle('backgroundColor', '#FF0000');
			
			return t;
		}
		


	}
}